package com.example.sunsg.okhttptest.util;

import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;

import com.example.sunsg.okhttptest.bean.Constant;
import com.example.sunsg.okhttptest.http.OkHttpManager;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * Created by sunsg on 15/11/7.
 */
public class DownLoadFileUtil {
    private String url;
    private String path;
    private OnDownLoadFileListener onDownLoadFileListener;
    private Object tag;

    private DownLoadFileUtil(Builder builder){
        this.url = builder.url;
        this.path = builder.path;
        this.onDownLoadFileListener = builder.onDownLoadFileListener;
        this.tag = builder.tag != null ? builder.tag : this;
    }

    private static Handler mHandler = new Handler(Looper.myLooper());
    /***
     * 下载文件
     * @param url
     * @param onDownLoadFileListener
     */
    public static void downFile(String url,OnDownLoadFileListener onDownLoadFileListener){
        connect(url, onDownLoadFileListener);
    }

    /***
     * 链接网络
     */
    private static void connect(final String url,final OnDownLoadFileListener onDownLoadFileListener){
        OkHttpManager.enqueue(url, new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                postMessage("网络链接错误", onDownLoadFileListener);
            }

            @Override
            public void onResponse(Response response) throws IOException {
                if (response.isSuccessful()) {
                    Headers headers = response.headers();
                    long totalLength = response.body().contentLength();
                    long temp = 0;
                    if (Constant.VALUE_RESPONSE_ACCEPT_RANGES.equals(headers.get(Constant.KEY_RESPONSE_ACCEPT_RANGES))) {
                        //支持断点续传
                        File file = new File(StorageUtils.mkdir() + "/" + parseFileName(url) + ".apk");
                        if (file.exists()) {
                            temp = file.length();
                        }
                    }
                    downLoadFile(url, temp, totalLength, onDownLoadFileListener);
                } else {
                    postMessage("数据错误 code ＝ " + response.code(), onDownLoadFileListener);
                }
            }
        });
    }

    /**
     * 真正下载文件
     */
    private static void downLoadFile(final String url,final long tempLength,final long totallength,final OnDownLoadFileListener onDownLoadFileListener){
        String rangeKey = Constant.KEY_REQUEST_RANGE;
        String rangeValue = String.format(Constant.VALUE_REQUEST_RANGE,tempLength,totallength);
        Headers headers = new Headers.Builder().add(rangeKey, rangeValue).build();
        OkHttpManager.enqueue(url, headers, new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                postMessage("网络链接错误", onDownLoadFileListener);
            }

            @Override
            public void onResponse(Response response) throws IOException {
                if (response.isSuccessful()) {

                    RandomAccessFile accessFile = null;
                    BufferedInputStream bis = null;
                    try {
                        bis = new BufferedInputStream(response.body().byteStream());
                        File file = new File(StorageUtils.mkdir() + "/" + parseFileName(url) + ".apk");
                        accessFile = new RandomAccessFile(file, "rwd");
                        if (accessFile.length() >= tempLength) {
                            accessFile.seek(tempLength);
                        }
                        byte[] buffer = new byte[1024 * 16];
                        int len = -1;
                        long present = tempLength;
                        while ((len = bis.read(buffer)) != -1) {
                            accessFile.write(buffer, 0, len);
                            present += len;
                            postProgress(present, totallength, url, onDownLoadFileListener);
                        }
                        if (present == totallength) {
                            postComplete(onDownLoadFileListener);
                        } else {
                            postMessage("下载失败 文件没有下载完成", onDownLoadFileListener);
                        }

                    } catch (Exception e) {
                        postMessage(e.getMessage().toString(), onDownLoadFileListener);
                    } finally {
                        if (bis != null) {
                            bis.close();
                        }

                        if (accessFile != null) {
                            accessFile.close();
                        }
//                        postMessage("下载失败 文件没有下载完成", onDownLoadFileListener);
                    }
                } else {
                    postMessage("数据错误 code ＝ " + response.code(), onDownLoadFileListener);
                }
            }
        });
    }


    /**
     * post 信息
     * @param message
     */
    private static void postMessage(final String message,final OnDownLoadFileListener onDownLoadFileListener){
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if(onDownLoadFileListener != null){
                    onDownLoadFileListener.onFailure(message);
                }
            }
        });
    }

    /**
     * post complete
     * @param onDownLoadFileListener
     */
    private static void postComplete(final OnDownLoadFileListener onDownLoadFileListener){
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if(onDownLoadFileListener != null){
                    onDownLoadFileListener.onComplete();
                }

            }
        });
    }

    /**
     * post progress
     * @param onDownLoadFileListener
     */
    private static void postProgress(final long finished,final long total,final Object tag,final OnDownLoadFileListener onDownLoadFileListener){
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if(onDownLoadFileListener != null){
                    onDownLoadFileListener.onProgress(finished, total, tag);
                }
            }
        });
    }

    /**
     * post pause
     * @param onDownLoadFileListener
     */
    private static void postPause(final OnDownLoadFileListener onDownLoadFileListener){
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if(onDownLoadFileListener != null){
                    onDownLoadFileListener.onPause();
                }
            }
        });
    }

    /**
     * post cancel
     * @param onDownLoadFileListener
     */
    private static void postCancel(final OnDownLoadFileListener onDownLoadFileListener){
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if(onDownLoadFileListener != null){
                    onDownLoadFileListener.onCancel();
                }
            }
        });
    }


    /**
     * parse 文件名
     */
    public static String parseFileName(String name){
        return String.valueOf(name.hashCode());
    }

    /**开始链接网络*/
    public void startConnect(){
        OkHttpManager.enqueue(url, new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                postMessage("网络链接错误", onDownLoadFileListener);
            }

            @Override
            public void onResponse(Response response) throws IOException {
                if (response.isSuccessful()) {
                    Headers headers = response.headers();
                    long totalLength = response.body().contentLength();
                    long temp = 0;
                    if (Constant.VALUE_RESPONSE_ACCEPT_RANGES.equals(headers.get(Constant.KEY_RESPONSE_ACCEPT_RANGES))) {
                        //支持断点续传
                        File file = new File(getPath());
                        if (file.exists()) {
                            temp = file.length();
                        }
                    }
                    startDownLoadFile(temp, totalLength);
                } else {
                    postMessage("数据错误 code ＝ " + response.code(), onDownLoadFileListener);
                }
            }
        });
    }

    /**
     * 真正下载文件
     */
    private  void startDownLoadFile(final long tempLength,final long totallength){
        String rangeKey = Constant.KEY_REQUEST_RANGE;
        String rangeValue = String.format(Constant.VALUE_REQUEST_RANGE,tempLength,totallength);
        Headers headers = new Headers.Builder().add(rangeKey, rangeValue).build();
        OkHttpManager.enqueue(url, headers, new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                postMessage("网络链接错误", onDownLoadFileListener);
            }

            @Override
            public void onResponse(Response response) throws IOException {
                if (response.isSuccessful()) {

                    RandomAccessFile accessFile = null;
                    BufferedInputStream bis = null;
                    try {
                        bis = new BufferedInputStream(response.body().byteStream());
                        File file = new File(getPath());
                        accessFile = new RandomAccessFile(file, "rwd");
                        if (accessFile.length() >= tempLength) {
                            accessFile.seek(tempLength);
                        }
                        byte[] buffer = new byte[1024 * 16];
                        int len = -1;
                        long present = tempLength;
                        while ((len = bis.read(buffer)) != -1) {
                            accessFile.write(buffer, 0, len);
                            present += len;
                            postProgress(present, totallength, tag, onDownLoadFileListener);
                        }
                        if (present == totallength) {
                            postComplete(onDownLoadFileListener);
                        } else {
                            postMessage("下载失败 文件没有下载完成", onDownLoadFileListener);
                        }

                    } catch (Exception e) {
                        postMessage(e.getMessage().toString(), onDownLoadFileListener);
                    } finally {
                        if (bis != null) {
                            bis.close();
                        }

                        if (accessFile != null) {
                            accessFile.close();
                        }
//                        postMessage("下载失败 文件没有下载完成", onDownLoadFileListener);
                    }
                } else {
                    postMessage("数据错误 code ＝ " + response.code(), onDownLoadFileListener);
                }
            }
        });
    }

    public String getPath() {
        if(TextUtils.isEmpty(path)){
            path = StorageUtils.mkdir() + File.separator +System.currentTimeMillis();
        }
        return path;
    }

    public static class Builder{
        private String url;
        private String path;
        private OnDownLoadFileListener onDownLoadFileListener;
        private Object tag;
        public Builder(){

        }

        public Builder url(String url){
            if(TextUtils.isEmpty(url)) new IllegalArgumentException("url == null or url=\"\"");
            this.url = url;
            return this;
        }

        public Builder path(String path){
            this.path = path;
            return this;
        }

        public Builder onDownLoadFileListener(OnDownLoadFileListener onDownLoadFileListener){
            this.onDownLoadFileListener = onDownLoadFileListener;
            return this;
        }

        public Builder tag(Object tag){
            this.tag = tag;
            return this;
        }

        public DownLoadFileUtil builder(){
            return new DownLoadFileUtil(this);
        }
    }


    /**
     * 下载文件监听借口
     */
    public interface OnDownLoadFileListener{
        void onStart();
        void onProgress(long finished,long total,Object tag);
        void onPause();
        void onComplete();
        void onCancel();
        void onFailure(String message);
    }

}
